float height=50;
void setup(){
  size(1000,1000);
  background(0);
  stroke(255);
  noLoop();
}
void draw(){
  TreeData cur=new TreeData("l0");
  cur.children.add(new TreeData("l1-1"));
  cur.children.add(new TreeData("l1-2"));
  TreeData cld=new TreeData("l1-3");
  cld.children.add(new TreeData("l2-1"));
  cld.children.add(new TreeData("l2-2"));
  cur.children.add(cld);
  TreeData cld1=new TreeData("l2-3");
  cld1.children.add(new TreeData("l3-1"));
  cld1.children.add(new TreeData("l3-2"));
  cld1.children.add(new TreeData("l3-3"));
  cld.children.add(cld1);
  println(cur.descendants());
  drawTree(cur,0,50,0);
}
void drawTree(TreeData tree,int level,float px,float py){
  float cy=0;
  float cx=px+200;
  
  if(tree.children.size()==0){
    cy=height+50*tree.descendants();
    height=cy+50;
    
  }else{
    cy=height+25*tree.descendants()-25;
  }
  text(tree.name,cx,cy);
  if(level!=0){
    ellipse(px+100,py-5,2,2);
    ellipse(cx-10,cy-5,2,2);
    line(px+100,py-5,cx-10,cy-5);
  }
  println(tree.name+"-"+cy+"-"+height);
  for(TreeData cld:tree.children){
    drawTree(cld,level+1,cx,cy);
  }
}
class TreeData{
  ArrayList<TreeData> children=new ArrayList<TreeData>();
  String name="abc";
  TreeData(String _name){
    name=_name;
  }
  int descendants(){
    int cnt=0;
    for(TreeData cld:children){
      if(cld.children.size()==0) {
        cnt++;
      }else{
        cnt+=cld.descendants();
      }
    }
    return cnt;
  }
}
